import axios, { AxiosRequestConfig } from "axios";
import { RegisterUser } from "./register/Register";
import { UpdatePassword } from "./update_password/UpdatePassword";
import { UserInfo } from "./update_info/Update_Info";
import { message } from "antd";

const axiosInstance = axios.create({
    baseURL: 'http://localhost:3000/',
    timeout: 3000
});

//请求拦截器(自动携带jwt)
axiosInstance.interceptors.request.use(function (request) {
    const accessToken = localStorage.getItem('access_token');

    if (accessToken) {
        request.headers.authorization = 'Bearer ' + accessToken;
    }

    return request;
})


interface PendingTask {
    config: AxiosRequestConfig
    resolve: Function
}
let refreshing = false;
const queue: PendingTask[] = [];

//AXIOS返回值是一个Promise实例 (ps: status code为200-299时 为成功,其他状态码返回一个状态为拒绝的Promise实例)
//1.用promise的catch方法(await不行,因为它会暂停代码执行,知道promise解决或拒绝,所以await后面的代码不会立即执行)
//2.用try catch 可解决await的问题
//3.用axios的错误拦截器,请求拒绝时进行一些处理  
axiosInstance.interceptors.response.use(
    (response) => {
        return response;
    },
    async (error) => {

        if (!error.response) { return Promise.reject(error); }
        let { data, config } = error.response;

        if (refreshing) {
            return new Promise((resolve) => {
                queue.push({
                    config,
                    resolve
                });
            });
        }

        if (data.code === 401 && !config.url.includes('/user/refresh')) {

            refreshing = true;
            const res = await refreshToken();

            if (res.status === 200) {
                console.log(res);
                queue.forEach(({ config, resolve }) => {
                    resolve(axiosInstance(config))
                })

                return axiosInstance(config);
            } else {
                message.error(res.data);

                setTimeout(() => {
                    window.location.href = '/login';
                }, 1500);
            }

            refreshing = false;

        } else {
            return error.response;
        }
    }
);



async function refreshToken() {
    const res = await axiosInstance.get('/user/refresh', {
        params: {
            refreshToken: localStorage.getItem('refresh_token')
        }
    });

    const { data } = res.data;
    localStorage.setItem('access_token', data.access_token || '');
    localStorage.setItem('refresh_token', data.refresh_token || '');
    return res;
}



export async function login(username: string, password: string) {
    return await axiosInstance.post('/user/login', {
        username,
        password
    });
}
export async function getUserInfo() {
    return await axiosInstance.get('/user/info');
}

export async function updateInfo(data: UserInfo) {
    return await axiosInstance.post('/user/update', data);
}

export async function updateUserInfoCaptcha() {
    return await axiosInstance.get('/user/update/captcha');
}





export async function registerCaptcha(email: string) {
    return await axiosInstance.get('/user/register-captcha', {
        params: { email: email }
    });
}
export async function register(registerUser: RegisterUser) {
    return await axiosInstance.post('/user/register', registerUser);
}





export async function updatePasswordCaptcha(email: string) {
    return await axiosInstance.get('/user/update_password/captcha', {
        params: { email: email }
    });
}
export async function updatePassword(data: UpdatePassword) {
    return await axiosInstance.post('/user/update_password', data);
}



export async function searchMeetingRoomList(name: string, capacity: number, equipment: string, pageNo: number, pageSize: number) {
    return await axiosInstance.get('/meeting-room/list', {
        params: {
            name,
            capacity,
            equipment,
            pageNo,
            pageSize
        }
    });
}


